package com.eatme.core.design.pattern.creational.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * 延迟初始化
 *
 */
public class LazySingleton {
    private static LazySingleton lazySingleton =null;

    private static boolean flag = true;

    private LazySingleton() {

        // 反射防御代码 在懒汉模式下无效
//        if (flag) {
//            flag =false;
//        }else {
//            throw new RuntimeException("单例构造器禁止反射调用");
//        }

        // 反射防御代码 在懒汉模式下无效
        if (lazySingleton!=null) {
            throw new RuntimeException("单例构造器禁止反射调用");
        }

    }

    // 和下面方法同样是对类加锁 即synchronized修饰static方法锁的是这个class
    public synchronized static LazySingleton getInstance() {
        if (lazySingleton==null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }



//    public synchronized static LazySingleton getInstance() {
//        synchronized (LazySingleton.class) {
//            if (lazySingleton==null) {
//                lazySingleton = new LazySingleton();
//            }
//        }
//        return lazySingleton;
//    }


//    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//        Class objectClass = LazySingleton.class;
//        Constructor constructor =objectClass.getDeclaredConstructor();
//        constructor.setAccessible(true);
//        LazySingleton o1 = LazySingleton.getInstance();
//
//        Field flag = o1.getClass().getDeclaredField("flag");
//        // 对懒汉模式字段(逻辑)防御的攻击
//        flag.setAccessible(true);
//        flag.set(o1,true);
//        LazySingleton o2 = (LazySingleton) constructor.newInstance();
//        System.out.println(o1);
//        System.out.println(o2);
//        System.out.println(o1 == o2);
//    }
}
